好了,总算开始进入正题,抛弃掉死板的说教模式,我们以一个虚构的新成立的项目组为例开始我们的 Kubernetes 探索。(以下统一将 Kubernetes 简写为 K8S) 项目组目前就只有一个成员,我们称他为小张。项目组刚成立的时候,小张也没想好,具体要做什么,但肯定要对外提供服务的,所以先向公司申请了一台服务器。
这台服务器可以用来做什么呢?跑服务,跑数据库,跑测试之类的都可以,我们将它所做的事情统称为工作(work) 那么,它便是工作节点 (worker Node) 对应于 K8S 中,这就是我们首先要认识的 Node 。
Node 可以是一台物理机,也可以是虚拟机,对于我们此处的项目来讲,这台服务器便是 K8S 中的 Node 。
当我们拿到这台服务器后,首先我们登录服务器查看下服务器的基本配置和信息。其实对于一个新加入 K8S 集群的 Node 也是一样,需要先检查它的状态,并将状态上报至集群的 master 。我们来看看服务器有哪些信息是我们所关心的。
首先,我们所关心的是我们服务器的 IP 地址,包括内网 IP 和外网 IP。对应于 K8S 集群的话这个概念是类似的,内部 IP 可在 K8S 集群内访问,外部 IP 可在集群外访问。
其次,我们也会关心一下我们的主机名,比如在服务器上执行 hostname
命令,便可得到主机名。K8S
集群中,每个 Node 的主机名也会被记录下来。当然,我们可以通过给 Kubelet 传递一个 --hostname-override
的参数来覆盖默认的主机名。 (Kubelet 是什么,我们后面会解释)
再之后,我们需要看下服务器的基本信息,比如看看系统版本信息, cat /etc/issue
或者
cat /etc/os-release
等方法均可查看。对于 K8S 集群会将每个 Node 的这些基础信息都记录下来。
我们通常也都会关注下,我们有几个核心的 CPU ,可通过 cat /proc/cpuinfo
查看,有多大的内存 通过 cat /proc/meminfo
或 free
等查看。对于
K8S 集群,会默认统计这些信息,并计算在此 Node 上可调度的 Pod 数量。(Pod 后面做解释)
对于我们拿到的服务器,我们关心上述的一些基本信息,并根据这些信息进行判断,这台机器是否能满足我们的需要。对
K8S 集群也同样,当判断上述信息均满足要求时候,便将集群内记录的该 Node 信息标记为 Ready
(Ready = True
),这样我们的服务器便正式的完成交付。我们来看下其他的部分。
现在小张拿到的服务器已经是可用状态,虽然此时尚不知要具体做什么,但姑且先部署一个主页来宣布下项目组的成立。
我们来看下一般情况下的做法,先写一个静态页面,比如叫 index.html 然后在服务器上启动一个 Nginx 或者其他任何 Web 服务器,来提供对 index.html 的访问。
Nginx 的安装及配置可参考 Nginx 的官方文档。最简单的配置大概类似下面这样(仅保留关键部分):
location / {
root /www;
index index.html;
}
对于 K8S 而言,我们想要的,能提供对 index.html 访问的服务便可理解为 Deployment 的概念,表明一种我们预期的目标状态。
而对于 Nginx 和 index.html 这个组合可以理解为其中的 Pod 概念,作为最小的调度单元。
虽然此刻部署的内容只有官网,但是为了避免单点故障,于是小张又申请了两台服务器(虽然看起来可能是浪费了点),现在要对原有的服务进行扩容,其实在新的服务器上我们所做的事情也还保持原样,部署 Nginx,提供对 index.html 的访问,甚至配置文件都完全是一样的。可以看到在这种情况下,增加一台服务器,我们需要做一件完全重复的事情。
本着不浪费时间做重复的工作的想法,小张想,要不然用 Ansible 来统一管理服务器操作和配置吧,但考虑到后续服务器上还需要部署其他的服务,常规的这样部署,容易干扰彼此的环境。
所以我们想到了用虚拟化的技术,但是根据一般的经验,类似 KVM 这样的虚拟化技术,可能在资源消耗上较多, 不够轻量级。而容器化相对来看,比较轻量级,也比较符合我们的预期,一次构建,随处执行。我们选择当前最热门的 Docker .
既然技术选型确定了,那很简单,在我们现在三台服务器上安装 Docker ,安装过程不再赘述,可以参考 Docker 的官方安装文档 。
此时,我们需要做的事情,也便只是将我们的服务构建成一个镜像,需要编写一个 Dockerfile,构建一个镜像并部署到每台服务器上便可。
聊了这么多,我们现在已经将我们的服务运行到了容器中,而此处的 Docker 便是我们选择的容器运行时。选择它的最主要原因,便是为了环境隔离和避免重复工作。
而 Docker 如果对应于 K8S 集群中的概念,便是 Container Runtime,这里还有其他的选择,比如 rkt,runc 和其他实现了 OCI 规范的运行时。
在这节里面,我们了解到了 Node 其实就是用于工作的服务器,它有一些状态和信息,当这些条件都满足一些条件判断时,Node 便处于 Ready 状态,可用于执行后续的工作。
Deployment 可理解为一种对期望状态的描述, Pod 作为集群中可调度的最小单元,我们会在后面详细讲解其细节。
Docker 是我们选择的容器运行时,可运行我们构建的服务镜像,减少在环境方面所做的重复工作,并且也非常便于部署。除了 Docker 外还存在其他的容器运行时。
了解到这些基本概念后,下节我们从宏观的角度上来认识 K8S 的整体架构,以便我们后续的学习和实践。